import datetime

from lxml import etree
from framework.common import util
from framework.common.pt_logger import logger
from framework.core.crawler_result import Result
from framework.core.crawler_task import Task


class ReviewParser(object):
    @staticmethod
    def parse(response, current_task):
        parent_result = current_task.parent_result
        content = response.content
        tree = etree.HTML(content)
        review_list = list()
        continue_yield_tasks = True

        div_review_list = tree.xpath("//div[@id='cm_cr-review_list']/div[@data-hook='review']")
        for div_review in div_review_list:
            review_dict = dict()
            reviewer = div_review.xpath("descendant::*/div[@data-hook='genome-widget']/a/div[@class='a-profile-content']/descendant::*/text()")
            review_dict["reviewer"] = util.fstring(reviewer)

            stars = div_review.xpath("descendant::*/i[@data-hook='review-star-rating']/descendant::*/text()")
            review_dict["stars"] = util.fstring(stars)

            title = div_review.xpath("descendant::*/a[@data-hook='review-title']/descendant::*/text()")
            review_dict["title"] = util.fstring(title)

            date = div_review.xpath("descendant::*/span[@data-hook='review-date']/text()")
            review_dict["date"] = date

            try:
                if current_task.metadata is not None and "stop_date" in current_task.metadata:
                    stop_date = current_task.metadata["stop_date"]
                    date_text = util.fregex(r"on (\w+ \d\d, \d\d\d\d)", util.fstring(date), 1)
                    date_date = datetime.datetime.strptime(date_text, '%B %d, %Y')
                    continue_yield_tasks = date_date > stop_date
            except Exception as ex:
                logger.error(f"parse date {date} error")
                logger.error(ex)

            review_body = div_review.xpath("descendant::*/span[@data-hook='review-body']/descendant::*/text()")
            review_dict["review_body"] = util.fstring(review_body)

            helpful_vote = div_review.xpath("descendant::*/span[@data-hook='helpful-vote-statement']/text()")
            review_dict["helpful_vote"] = util.fstring(helpful_vote)

            comments_count = div_review.xpath("descendant::*/span[@class='a-size-base']/text()")
            review_dict["comments_count"] = util.fstring(comments_count)

            review_list.append(review_dict)

        next_page_url = tree.xpath("//ul[@class='a-pagination']/li[@class='a-last']/a/@href")
        next_page_url = util.fstring(next_page_url)
        temp_array = next_page_url.split("pageNumber=")
        next_page_number = int(temp_array[1]) if len(temp_array) > 1 else None
        new_task_list = None
        if continue_yield_tasks and next_page_number and next_page_number <= 10:  # JimmyMo: grab max 10 pages of review
            new_task_list = Task.create_tasks("https://www.amazon.com" + util.fstring(next_page_url), parser=current_task.parser,
                                              parent_result=None,
                                              metadata=current_task.copy_metadata())

        review_result = Result.from_task(task=current_task, reviews=review_list)
        return review_result, new_task_list


if __name__ == "__main__":
    import json
    from framework.mock import MockResponse, MockTask
    parser = ReviewParser()
    sampler_local_html = "./samples/review_B01N1Z2HUS.html"
    response = MockResponse(sampler_local_html)
    parser.parse(response, MockTask(None))